using System;
using Windows.UI.Xaml;
namespace System.Windows.Interactivity
{
	/// <summary>
	/// Static class that owns the Triggers and Behaviors attached properties. Handles propagation of AssociatedObject change notifications.
	/// </summary>
	public static class Interaction
	{
		/// <summary>
		/// This property is used as the internal backing store for the public Triggers attached property.
		/// </summary>
		/// <remarks>
		/// This property is not exposed publicly. This forces clients to use the GetTriggers and SetTriggers methods to access the
		/// collection, ensuring the collection exists and is set before it is used.
		/// </remarks>
		private static readonly DependencyProperty TriggersProperty = DependencyProperty.RegisterAttached("ShadowTriggers", typeof(TriggerCollection), typeof(Interaction), new PropertyMetadata(null, new PropertyChangedCallback(Interaction.OnTriggersChanged)));
		/// <summary>
		/// This property is used as the internal backing store for the public Behaviors attached property.
		/// </summary>
		/// <remarks>
		/// This property is not exposed publicly. This forces clients to use the GetBehaviors and SetBehaviors methods to access the
		/// collection, ensuring the collection exists and is set before it is used.
		/// </remarks>
		private static readonly DependencyProperty BehaviorsProperty = DependencyProperty.RegisterAttached("ShadowBehaviors", typeof(BehaviorCollection), typeof(Interaction), new PropertyMetadata(null, new PropertyChangedCallback(Interaction.OnBehaviorsChanged)));
		/// <summary>
		/// Gets or sets a value indicating whether to run as if in design mode.
		/// </summary>
		/// <value>
		/// 	<c>True</c> if [should run in design mode]; otherwise, <c>False</c>.
		/// </value>
		/// <remarks>Not to be used outside unit tests.</remarks>
		internal static bool ShouldRunInDesignMode
		{
			get;
			set;
		}
		/// <summary>
		/// Gets the TriggerCollection containing the triggers associated with the specified object.
		/// </summary>
		/// <param name="obj">The object from which to retrieve the triggers.</param>
		/// <returns>A TriggerCollection containing the triggers associated with the specified object.</returns>
		public static TriggerCollection GetTriggers(DependencyObject obj)
		{
			TriggerCollection triggerCollection = (TriggerCollection)obj.GetValue(Interaction.TriggersProperty);
			if (triggerCollection == null)
			{
				triggerCollection = new TriggerCollection();
				obj.SetValue(Interaction.TriggersProperty, triggerCollection);
			}
			return triggerCollection;
		}
		/// <summary>
		/// Gets the <see cref="T:System.Windows.Interactivity.BehaviorCollection" /> associated with a specified object.
		/// </summary>
		/// <param name="obj">The object from which to retrieve the <see cref="T:System.Windows.Interactivity.BehaviorCollection" />.</param>
		/// <returns>A <see cref="T:System.Windows.Interactivity.BehaviorCollection" /> containing the behaviors associated with the specified object.</returns>
		public static BehaviorCollection GetBehaviors(DependencyObject obj)
		{
			BehaviorCollection behaviorCollection = (BehaviorCollection)obj.GetValue(Interaction.BehaviorsProperty);
			if (behaviorCollection == null)
			{
				behaviorCollection = new BehaviorCollection();
				obj.SetValue(Interaction.BehaviorsProperty, behaviorCollection);
			}
			return behaviorCollection;
		}
		/// <exception cref="T:System.InvalidOperationException">Cannot host the same BehaviorCollection on more than one object at a time.</exception>
		private static void OnBehaviorsChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
		{
			BehaviorCollection behaviorCollection = (BehaviorCollection)args.OldValue;
			BehaviorCollection behaviorCollection2 = (BehaviorCollection)args.NewValue;
			if (behaviorCollection != behaviorCollection2)
			{
				if (behaviorCollection != null && ((IAttachedObject)behaviorCollection).AssociatedObject != null)
				{
					behaviorCollection.Detach();
				}
				if (behaviorCollection2 != null && obj != null)
				{
					if (((IAttachedObject)behaviorCollection2).AssociatedObject != null)
					{
						throw new InvalidOperationException("CannotHostBehaviorCollectionMultipleTimesExceptionMessage");
					}
					behaviorCollection2.Attach(obj);
				}
			}
		}
		/// <exception cref="T:System.InvalidOperationException">Cannot host the same TriggerCollection on more than one object at a time.</exception>
		private static void OnTriggersChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
		{
			TriggerCollection triggerCollection = args.OldValue as TriggerCollection;
			TriggerCollection triggerCollection2 = args.NewValue as TriggerCollection;
			if (triggerCollection != triggerCollection2)
			{
				if (triggerCollection != null && ((IAttachedObject)triggerCollection).AssociatedObject != null)
				{
					triggerCollection.Detach();
				}
				if (triggerCollection2 != null && obj != null)
				{
					if (((IAttachedObject)triggerCollection2).AssociatedObject != null)
					{
						throw new InvalidOperationException("CannotHostTriggerCollectionMultipleTimesExceptionMessage");
					}
					triggerCollection2.Attach(obj);
				}
			}
		}
		/// <summary>
		/// A helper function to take the place of FrameworkElement.IsLoaded, as this property is not available in Silverlight.
		/// </summary>
		/// <param name="element">The element of interest.</param>
		/// <returns>True if the element has been loaded; otherwise, False.</returns>
        internal static bool IsElementLoaded(FrameworkElement element)
        {
            return true; // element.IsLoaded;
        }
	}
}
